spring boot-mybatis开发速成指南
2022-12-01 22:26:10
技术
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run". We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.
本文的目的:了解一个spring boot项目结构的关系,知道我们应该在哪个部分做什么事
参考项目结构
|_java.com.cy.store
|_aop
|_config
|_controller
|_entity
|_interceptor
|_mapper
|_service
|_ex
|_impl
|_util
|_vo
XXXApplication
|_resource
|_mapper
|_static
|_templates
application.yml/application.properties
不同项目项目结构不一样,但一般来讲,理清controller控制层、service业务逻辑层、mapper(dao)数据访问层三层关系即可
推荐项目学习
该视频下方有热心小伙伴的文档笔记整理
个人认为只看一个功能即可,其他大同小异,我只了解完用户注册剩下的大概看看就行了,主要是了解一个spring boot项目的整体思路
三层关系
controller、service、mapper三层关系梳理1
controller、service、mapper三层关系梳理2
数据库(表)设计
实体层(编写实体类)
entity(或叫model)实体,该层存放实体类,属性值与数据库中的属性值保持一致,实现set和get方法,可使用@Data注解自动生成
多个类拥有同一些属性,可以把这些属性抽取成一个公共基类这样方便我们管理。例如数据库许多实体类都需要有日志相关的四个属性:创建者和时间以及修改者和时间,则可先创建包含这些属性的基类,然后其他实体类再继承这个基类
持久层 (java对象与sql映射)(Mapper接口与xml映射文件绑定)
mapper(或叫dao),为映射
的意思;
dao(data access object),数据访问对象
持久层
的意思是使数据可以永久保持地存储,可以直接理解为对数据库的CRUD等操作,就是把持久的动作封装成一个独立的层。这是为了降低功能代码之间的关联,创建一个更清晰的抽象,提高代码的内聚力,降低代码的耦合度,提高可维护性和复用性.
Mybatis
对jdbc 的操作数据库的过程进行封装,通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
总之:
- 确定好需要写的sql;
- 在java文件夹下的mapper包编写持久层接口(Mapper接口):
XxxxMapper
,在接口中定义需要实现的抽象方法;- 在resource文件夹下的mapper包编写xml映射文件:
XxxxMapper.xml
,编写对应Mapper接口的方法的sql(抽象方法的映射配置),接口与xml文件绑定
1)Mapper 接口与 XML 文件的绑定是通过 XML 里 mapper 标签的 namespace 值与 Mapper 接口的 包路径.接口名 进行绑定
2) Mapper 接口的方法名与 XML 文件中的 sql、select、insert、update、delete 标签的 id 参数值进行绑定
在配置文件中说明xml配置:mybatis.mapper-locations=classpath:mapper/*.xml
业务逻辑层
service 服务,此处翻译为业务比较合适,service层处理业务逻辑 mapper层是对数据库的操作,不涉及业务逻辑,具体是对某张表的增删查改
service是业务逻辑,一个业务(功能)对应多项操作,需要有数据的处理流程和逻辑
流程:先做什么,再做什么
逻辑:能做什么,不能做什么
例:用户注册
mapper层:UserMapper
中定义insert()
方法(插入用户数据)、findByUsername()
方法(根据用户名查询数据)
service层:UserService
中定义的一个业务逻辑(功能)为reg()
(用户注册),reg()
在数据库层面的理解其实就是insert()
,但是insert()
不涉及数据处理流程和逻辑
reg()的业务逻辑:先根据输入的用户名查询是否已存在用户数据(调用UserMapper
的findByUsername()
),如果不存在则插入用户数据(调用用UserMapper
的insert()
),如果存在则抛出用户已存在的异常。
在service包中,先在IUserService接口
中定义reg()
的抽象方法,然后在service.impl
(implement:实现)包中的UserServiceImpl
实现类中实现reg()
方法
总之:
- 规划可能出现的异常,如用户名重复等,写在Service.ex包下
- 直接在在Service包下编写业务层接口(service接口):
IXxxxService
,该命名方式开头的I表示接口,接口中定义要实现的抽象方法——业务逻辑(功能)- 在service.impl包下编写service接口的实现类:
XxxxServiceImpl
,实现相应service接口中的抽象方法
控制层
controller的注解1
controller的注解2
controller请求与响应
controller请求与响应生动讲解
controller请求与响应生动讲解(续)
Controller 控制器
,与前端和service层交互,
把用户提交来的请求通过对URL的匹配,分配不同的接收器,再进行处理,然后向用户返回结果。
从HTTP请求中获取信息,提取参数,并将其分发给不同的处理服务(service层),根据实际需求调用不同的service定义的方法来处理不同业务,并向前端返回service层处理后的数据,他的重点就在于如何从HTTP请求中获得信息,提取参数,并分发给不同的处理服务。接收和响应请求,校验数据
controller负责管理service,service负责实施
例:用户注册
@RestController
@RequestMapping("users")
public class UserController extends BaseController {
@Autowired
private IUserService userService;
@RequestMapping("reg")
public JsonResult<Void> reg(User user) {
// 调用业务对象执行注册
userService.reg(user);
// 返回
return new JsonResult<Void>(200);
}
//省略其他代码
}
在UserController中实例化IUserService
对象userService
;
@RequestMapping("users")
、@RequestMapping("reg")
请求映射,将http请求路径映射到Controller方法上;
当用户在前端点击注册后,前端请求通过.../users/reg的路径发送给后端的UserController,执行@RequestMapping("reg")
下的reg()
方法;
注意这里的reg()是Controller层的,不负责“用户注册”这个业务的实现,它会调用Service层真正实现“用户注册”业务逻辑的userService.reg()
;
然后userService.reg()
调用mapper层的数据库操作方法findByUsername()
和insert()
,根据映射的xml文件通过Mybatis执行sql连接操作数据库,把数据写入数据库,完成该业务逻辑,但还需要返回响应结果
.../users
请求路径是映射到@RequestMapping("users")
下面的UserController类;.../users/reg
请求路径映射到@RequestMapping("users")
之下的@RequestMapping("reg")
下面的reg方法
再看一下上面的
return new JsonResult<Void>(200);
JsonResult
是自定义的响应结果类,统一返回结果
上面的200
表示正常,即注册成功,如果成功执行了reg方法,则会创建一个JsonResult类的对象,其中state(状态码)属性值设置为200
自定义的JsonResult类包含属性state(状态码)、message(状态描述信息)、data(数据),这里注册只需要知道是否操作成功就只返回状态码,如查询等业务则会还需要返回数据等
下面看一下前端代码,这个例子的前端用的是Thymeleaf模板引擎
<script type="text/javascript">
$("#btn-reg").click(function() {
$.ajax({
url: "/users/reg",
type: "POST",
data: $("#form-reg").serialize(),
dataType: "json",
success: function(json) {
if (json.state == 200) {
alert("注册成功!");
// location.href = "login.html";
} else {
alert("注册失败!" + json.message);
}
}
});
});
</script>
第四行的url即为上面提到前端的请求路径,该请求为post请求、提交数据,数据来源于id等于第六行"#form-reg"
的表单(form),内容为用户注册所需要的信息,与User类属性一致,然后转化为json对象传给Controller,该对象(实参)在Controller中为User类的对象user(形参)
public JsonResult<Void> reg(User user)
后端的Controller接收该请求,当处理完请求后返回结果给前端
如上success: function(json)
表示请求成功并返回信息(响应请求),这里括号里的json
就是后端Controller返回的结果,即一个JsonResult类的对象(实参),其state属性值为200,在前端中这个对象被命名为json(形参),那么Controller返回结果成功则json.state==200.
以上即为前后端交互的流程,Controller负责接收请求和响应请求,调用Service处理业务,但自身不涉及业务逻辑
总之:
- 考虑要实现一个业务逻辑,用户在前端界面操作,该操作会从前端向后端传递什么,后端处理完该业务逻辑需要返回给前端什么
- 设计请求与响应,例: 请求路径:/users/reg 请求参数:User user 请求类型:POST 响应结果:JsonResult
- 在Controller包下编写控制器类:
XxxxController
,在类中实例化需要调用的service对象:xxxxServiceXxxxController
中编写要实现业务的控制方法,包括请求参数与响应结果(返回值),调用xxxxService对象的xxx()方法- 使用
@RequestMapping
等注解映射控制方法的请求路径,实现前后端的交互
总结
用户操作前端界面,需要实现某种业务--前端发送请求给后端controller--controller接收请求,调用service处理该业务 --service处理业务调用mapper的数据库操作方法 --mapper方法与mapper.xml存在映射关系;--Mybatis执行sql--service处理业完毕--controller返回响应结果--前端返回反馈给用户
用户操作前端界面,需要实现某种业务(<?> 操作内容){
//前端api接口
<操作反馈> 前端发送请求给后端controller (){
<?> 请求路径
<?> 请求参数
<?> 请求类型
<?> 响应结果
//controller层
<响应结果> controller接收请求,调用service处理该业务 (<?> 请求参数){
//service层
service处理业务时,调用mapper的数据库操作方法 (<?> 请求参数){
//mapper层
mapper方法与mapper.xml存在映射关系;
//resource文件夹下的mapper的xml文件
执行sql;
}
}
}
}
考虑的时候可以是前端---controller---service---dao---database ; 写代码的时候则database---dao---service---controller---前端
总而言之,言而总之
在mapper层
- 确定好需要写的sql;
- 在java文件夹下的mapper包编写持久层接口(Mapper接口):
XxxxMapper
,在接口中定义需要实现的抽象方法;- 在resource文件夹下的mapper包编写xml映射文件:
XxxxMapper.xml
,编写对应Mapper接口的方法的sql(抽象方法的映射配置),接口与xml文件绑定
在service层
- 规划可能出现的异常,如用户名重复等,写在Service.ex包下
- 直接在在Service包下编写业务层接口(service接口):
IXxxxService
,该命名方式开头的I表示接口,接口中定义要实现的抽象方法——业务逻辑(功能)- 在service.impl包下编写service接口的实现类:
XxxxServiceImpl
,实现相应service接口中的抽象方法
在controller层
- 考虑要实现一个业务逻辑,用户在前端界面操作,该操作会从前端向后端传递什么,后端处理完该业务逻辑需要返回给前端什么
- 设计请求与响应,例: 请求路径:/users/reg 请求参数:User user 请求类型:POST 响应结果:JsonResult
- 在Controller包下编写控制器类:
XxxxController
,在类中实例化需要调用的service对象:xxxxServiceXxxxController
中编写要实现业务的控制方法,包括请求参数与响应结果(返回值),调用xxxxService对象的xxx()方法- 使用
@RequestMapping
等注解映射控制方法的请求路径,实现前后端的交互